package Java2Test.Reflect.Reflect4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        // 通过全类名获取Student类的Class对象
        Class<?> clazz = Class.forName("Java2Test.Reflect.Reflect4.Student");

        // 获取Student类中名为"eat"且参数类型为String的方法
        // 解释："eat"需要加双引号是因为getDeclaredMethod()的第一个参数是
        // 方法名称的字符串表示，反射机制需要通过字符串来指定目标方法
        Method eat = clazz.getDeclaredMethod("eat", String.class);

        // 获取Student类中声明的所有方法（包括私有、受保护和公共方法）
        Method[] declaredMethods = clazz.getDeclaredMethods();
        // 遍历并打印所有声明方法的名称
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }

        // 获取eat方法的修饰符（返回值为整数，可通过Modifier类解析）
        int modifiers = eat.getModifiers();
        System.out.println(modifiers);

        // 获取eat方法的名称
        String name = eat.getName();
        System.out.println(name);

        // 获取eat方法的参数信息并打印
        Parameter[] parameters = eat.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        // 获取eat方法声明抛出的异常类型并打印
        Class<?>[] exceptionTypes = eat.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        // 创建Student类的实例
        Student s = new Student();

        // 设置eat方法的可访问性（突破私有访问限制）
        eat.setAccessible(true);

        // 通过反射调用eat方法，传递实例s和参数"汉堡"，返回方法执行结果
        // 解释：此处eat是已经获取到的Method对象，invoke()是Method类的实例方法
        // 直接通过对象调用方法，所以不需要双引号
        // 解释：不直接使用s.eat("汉堡")是因为：
        // 1. eat()是私有方法，直接调用会编译错误
        // 2. 反射允许在运行时动态调用方法，增加程序灵活性（如插件系统）
        Object result = eat.invoke(s, "汉堡");

        // 打印方法返回结果
        System.out.println(result);
    }
}